package scalab.tasks.archives

import java.util.zip._
import java.io._

/**
* Allows to build Zip archives.
*/

trait Zip extends Archive{

	def makeArchive(path: String): Boolean = {
		
		try{
			makeZip(new ZipOutputStream(new FileOutputStream(path)))
		}
		catch{
			case e: Exception => 
				error(e.getMessage)
				false
		}
	}

	//todo: add try / catch / finalize
	protected def makeZip(zos: ZipOutputStream): Boolean = {
		import scalab.utils.Path
		import java.util.zip.ZipEntry

		import scalab.utils.Digest

		coupledInputs.elements foreach { p =>
			val deps = p._1.sources
			p._2.sources.foreach {dir =>
				(deps filter {d => d.canonicalPath.startsWith(dir.canonicalPath)}) foreach {d => 
					val entryName = Path.removePrefix(d, dir)
					val entry = new ZipEntry(entryName)
					zos.putNextEntry(entry)
					
					if(!d.isDirectory){				
						
						val buffer : Array[byte] = new Array(1024)
						val fis: FileInputStream = new FileInputStream(d)
						var len: Int = fis.read(buffer)
  					while(len > 0){
    					zos.write(buffer, 0, len)
    					len = fis.read(buffer)
  					} 
						fis.close
					}
					zos.closeEntry
				}
			}
			zos.close
		}
		true 
	}
}

object Zip{

	import scalab.core.component.Component
	
	def apply(destFile: String): Zip = new Zip{
		override val name = "Zip"
		override val destinationArchive: String = destFile
	}

	def apply(destFile: String, components: Iterable[Component]): Zip = new Zip{
		override val name = "Zip"
		override val destinationArchive: String = destFile
		components foreach {c => c -> archiveInput(c)}
	}

	def apply(destFile: String, components: Component*): Zip = apply(destFile, components)
}
